function res = GroupCharacterization(obj, varargin)
    L = log4m.getLogger;
    
    p=inputParser;
    p.addRequired('Temperature', @(x) x>0);
    p.addRequired('PumpPower', @(x) x>0);
    p.addRequired('ProbePower', @(x) x>0);
    p.addRequired('PumpFrequency', @(x) x>0);
    p.addRequired('ProbeFrequency', @(x) x>0);
    p.addParameter('AOMVoltage', 1.0);
    p.addParameter('EaterVoltage', 0.4);
    p.addParameter('initialBx0', 0.04);
    p.addParameter('initialBy0', -1.3);
    p.addParameter('amplitudeTransX', 0.1, @(x) x>0 && x<1);
    p.addParameter('amplitudeTransY', 0.3, @(x) x>0 && x<1);
    p.addParameter('Xe129Coeff', 253.880/5.939);
    p.addParameter('EstXe129T2', 50.0);
    p.addParameter('EstXe131T2', 20.0);
    p.addParameter('EstXe129T1', 180.0);
    p.addParameter('EstXe131T1', 20.0);
    p.addParameter('description', '', @ischar);
    p.parse(varargin{:});
    %%
    descriptionStr = sprintf('Temp%3.1fdegC_AOM%4.3fV_EATER%4.3fV_%s',p.Results.Temperature, p.Results.AOMVoltage, p.Results.EaterVoltage, p.Results.description);
    
    getReporter;
    rpt.NewGroup(sprintf('Gyroscope Characterization Group, T=%d degC, PumpPower=%5.3fmW, ProbePower=%5.3fmW', p.Results.Temperature, p.Results.PumpPower,p.Results.ProbePower));
    rpt.MainText('In this group, we perform a set of measurements to characterize the parametric magnetometer and the nmr gyroscope.');
    rpt.TextEnter();
    
    dataCell = {'pump power (mW)',                     'pump freq (THz)',                        'probe power (mW)',                     'probe freq (THz)',                         'cell temp (degC)'; ...
                sprintf('%8.5f', p.Results.PumpPower), sprintf('%8.5f', p.Results.PumpFrequency), sprintf('%3.2f', p.Results.ProbePower), sprintf('%8.5f', p.Results.ProbeFrequency), sprintf('%3.1f', p.Results.Temperature)};
    rpt.AppendTable(dataCell, 'Unchanged Parameters.');
    res.condition = dataCell;
    %%
    
    obj.initialize; pause(1.0);
    obj.aom.setDC(p.Results.AOMVoltage); pause(1.0);    
    obj.eater.setDC(p.Results.EaterVoltage); pause(1.0);
    
    res.MainField = obj.GetMainField('description', descriptionStr, 'isReport', true); pause(1.0);
    res.WorkingPoint = obj.GetWorkingPoint('initialBx0', p.Results.initialBx0, 'initialBy0', p.Results.initialBy0, ...
                                           'amplitudeTransX', p.Results.amplitudeTransX, 'amplitudeTransY', p.Results.amplitudeTransY, 'description', descriptionStr, 'isReport', true); pause(1.0);
    obj.LockTransverseField(); pause(1.0);
    res.MagnetometerSensitivity = obj.GetMagnetometerSensitivity('description', descriptionStr, 'isReport', true); pause(1.0);
    res.MagnetometerBandwidth = obj.GetMagnetometerBandwidth('description', descriptionStr, 'isReport', true); pause(1.0);
    
    guessFreq129 = obj.MainField.bz0*p.Results.Xe129Coeff;
    guessFreq131 = guessFreq129/3.37340;
    
    res.FIDXe129Signal = obj.GetFIDXe129Signal(3.0*p.Results.EstXe129T2, 'guessFrequency', guessFreq129, 'description', descriptionStr, 'isReport', true); pause(1.0);
    res.FIDXe131Signal = obj.GetFIDXe131Signal(3.0*p.Results.EstXe131T2, 'guessFrequency',  guessFreq131, 'description', descriptionStr, 'isReport', true); pause(1.0);
    res.XeDriving = obj.GetXeDriving('recordTime', 2.0*p.Results.EstXe129T1, 'description', descriptionStr, 'isReport', true); pause(1.0);
    res.XePhaseNoiseOpen = obj.GetXePhaseNoise('nCol', 4096, 'average', 400, 'description', [descriptionStr '_OpenLoop'], 'isReport', true); pause(1.0);
    
    obj.LockXe129('pVal', 1e-4, 'iVal', 150e-6); pause(1.0);
    input('Please check Xe129 locking status, and press any key to continue.');
    
    res.XePhaseNoiseLock = obj.GetXePhaseNoise('nCol', 4096, 'average', 400, 'description', [descriptionStr '_CloseLoop'], 'isReport', true); pause(1.0);
    obj.UnlockXe129(); pause(1.0);
    obj.by129.disableDriver(); pause(1.0);
    obj.by131.disableDriver(); pause(1.0);
    res.RelaxationXe129 = obj.GetRelaxationXe129(5.0*p.Results.EstXe129T1, 'description', descriptionStr, 'isReport', true); pause(1.0);
    res.RelaxationXe131 = obj.GetRelaxationXe131(5.0*p.Results.EstXe131T1, 'description', descriptionStr, 'isReport', true); pause(1.0);
    res.Xe129T1Rho = obj.GetXe129T1Rho(3.0*p.Results.EstXe129T1, 'description', descriptionStr, 'isReport', true); 
    L.info('MeasurementPackage', sprintf('Waiting Xe129 for relaxtion [%d s]...', 5.0*p.Results.EstXe129T1));
    pause(5.0*p.Results.EstXe129T1);
    res.Xe131T1Rho = obj.GetXe131T1Rho(3.0*p.Results.EstXe131T1, 'description', descriptionStr, 'isReport', true); pause(1.0);
    
    %%
    getSession;
    sess.addData('MeasurementPackage', res, descriptionStr);
end

